/**
 * 文件上传工具类
 * 提供文件上传相关的通用工具函数
 */

import { ElMessage } from 'element-plus'

/**
 * 文件类型验证
 */
export interface FileTypeConfig {
  // 允许的文件扩展名
  allowedExtensions?: string[]
  // 允许的MIME类型
  allowedMimeTypes?: string[]
  // 禁止的文件扩展名
  blockedExtensions?: string[]
}

/**
 * 文件大小配置
 */
export interface FileSizeConfig {
  // 最大文件大小（MB）
  maxSize?: number
  // 最小文件大小（KB）
  minSize?: number
}

/**
 * 图片尺寸配置
 */
export interface ImageDimensionConfig {
  // 最小宽度
  minWidth?: number
  // 最小高度
  minHeight?: number
  // 最大宽度
  maxWidth?: number
  // 最大高度
  maxHeight?: number
  // 宽高比限制 (width/height)
  aspectRatio?: number
  // 宽高比容差
  aspectRatioTolerance?: number
}

/**
 * 验证文件类型
 */
export const validateFileType = (file: File, config: FileTypeConfig): boolean => {
  const { allowedExtensions, allowedMimeTypes, blockedExtensions } = config
  
  // 获取文件扩展名
  const fileExtension = file.name.split('.').pop()?.toLowerCase()
  const fileMimeType = file.type
  
  // 检查禁止的扩展名
  if (blockedExtensions && fileExtension && blockedExtensions.includes(fileExtension)) {
    ElMessage.error(`不允许上传 .${fileExtension} 类型的文件`)
    return false
  }
  
  // 检查允许的扩展名
  if (allowedExtensions && allowedExtensions.length > 0) {
    if (!fileExtension || !allowedExtensions.includes(fileExtension)) {
      ElMessage.error(`只允许上传以下类型的文件: ${allowedExtensions.join(', ')}`)
      return false
    }
  }
  
  // 检查允许的MIME类型
  if (allowedMimeTypes && allowedMimeTypes.length > 0) {
    const isAllowed = allowedMimeTypes.some(type => {
      if (type.endsWith('*')) {
        return fileMimeType.startsWith(type.slice(0, -1))
      }
      return fileMimeType === type
    })
    
    if (!isAllowed) {
      ElMessage.error(`不支持的文件类型: ${fileMimeType}`)
      return false
    }
  }
  
  return true
}

/**
 * 验证文件大小
 */
export const validateFileSize = (file: File, config: FileSizeConfig): boolean => {
  const { maxSize, minSize } = config
  const fileSizeInMB = file.size / (1024 * 1024)
  const fileSizeInKB = file.size / 1024
  
  if (maxSize && fileSizeInMB > maxSize) {
    ElMessage.error(`文件大小不能超过 ${maxSize}MB`)
    return false
  }
  
  if (minSize && fileSizeInKB < minSize) {
    ElMessage.error(`文件大小不能小于 ${minSize}KB`)
    return false
  }
  
  return true
}

/**
 * 验证图片尺寸
 */
export const validateImageDimensions = (
  file: File,
  config: ImageDimensionConfig
): Promise<boolean> => {
  return new Promise((resolve) => {
    const { minWidth, minHeight, maxWidth, maxHeight, aspectRatio, aspectRatioTolerance = 0.1 } = config
    
    const img = new Image()
    
    img.onload = () => {
      const { width, height } = img
      
      // 检查最小尺寸
      if (minWidth && width < minWidth) {
        ElMessage.error(`图片宽度不能小于 ${minWidth}px，当前: ${width}px`)
        resolve(false)
        return
      }
      
      if (minHeight && height < minHeight) {
        ElMessage.error(`图片高度不能小于 ${minHeight}px，当前: ${height}px`)
        resolve(false)
        return
      }
      
      // 检查最大尺寸
      if (maxWidth && width > maxWidth) {
        ElMessage.error(`图片宽度不能大于 ${maxWidth}px，当前: ${width}px`)
        resolve(false)
        return
      }
      
      if (maxHeight && height > maxHeight) {
        ElMessage.error(`图片高度不能大于 ${maxHeight}px，当前: ${height}px`)
        resolve(false)
        return
      }
      
      // 检查宽高比
      if (aspectRatio) {
        const currentRatio = width / height
        const diff = Math.abs(currentRatio - aspectRatio)
        const tolerance = aspectRatio * aspectRatioTolerance
        
        if (diff > tolerance) {
          ElMessage.error(`图片宽高比不符合要求，期望: ${aspectRatio.toFixed(2)}, 当前: ${currentRatio.toFixed(2)}`)
          resolve(false)
          return
        }
      }
      
      resolve(true)
    }
    
    img.onerror = () => {
      ElMessage.error('图片格式不正确或文件已损坏')
      resolve(false)
    }
    
    img.src = URL.createObjectURL(file)
  })
}

/**
 * 格式化文件大小
 */
export const formatFileSize = (size: number): string => {
  if (size === 0) return '0 B'
  
  const units = ['B', 'KB', 'MB', 'GB', 'TB']
  let unitIndex = 0
  let fileSize = size
  
  while (fileSize >= 1024 && unitIndex < units.length - 1) {
    fileSize /= 1024
    unitIndex++
  }
  
  return `${fileSize.toFixed(1)} ${units[unitIndex]}`
}

/**
 * 获取文件扩展名
 */
export const getFileExtension = (filename: string): string => {
  return filename.split('.').pop()?.toLowerCase() || ''
}

/**
 * 获取文件图标类型
 */
export const getFileIconType = (filename: string, mimeType?: string): string => {
  const extension = getFileExtension(filename)
  
  // 图片文件
  if (mimeType?.startsWith('image/') || ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp'].includes(extension)) {
    return 'image'
  }
  
  // 视频文件
  if (mimeType?.startsWith('video/') || ['mp4', 'avi', 'mov', 'wmv', 'flv', 'webm'].includes(extension)) {
    return 'video'
  }
  
  // 音频文件
  if (mimeType?.startsWith('audio/') || ['mp3', 'wav', 'flac', 'aac', 'ogg'].includes(extension)) {
    return 'audio'
  }
  
  // 文档文件
  if (['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'rtf'].includes(extension)) {
    return 'document'
  }
  
  // 压缩文件
  if (['zip', 'rar', '7z', 'tar', 'gz'].includes(extension)) {
    return 'archive'
  }
  
  // 代码文件
  if (['js', 'ts', 'html', 'css', 'java', 'py', 'cpp', 'c', 'php'].includes(extension)) {
    return 'code'
  }
  
  return 'file'
}

/**
 * 生成唯一文件名
 */
export const generateUniqueFileName = (originalName: string): string => {
  const timestamp = Date.now()
  const random = Math.random().toString(36).substring(2, 8)
  const extension = getFileExtension(originalName)
  const nameWithoutExt = originalName.substring(0, originalName.lastIndexOf('.'))
  
  return `${nameWithoutExt}_${timestamp}_${random}.${extension}`
}

/**
 * 检查文件是否为图片
 */
export const isImageFile = (file: File): boolean => {
  return file.type.startsWith('image/')
}

/**
 * 检查文件是否为视频
 */
export const isVideoFile = (file: File): boolean => {
  return file.type.startsWith('video/')
}

/**
 * 检查文件是否为音频
 */
export const isAudioFile = (file: File): boolean => {
  return file.type.startsWith('audio/')
}

/**
 * 预设的文件类型配置
 */
export const FILE_TYPE_PRESETS = {
  // 图片文件
  image: {
    allowedExtensions: ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp'],
    allowedMimeTypes: ['image/*']
  },
  
  // 文档文件
  document: {
    allowedExtensions: ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt'],
    allowedMimeTypes: [
      'application/pdf',
      'application/msword',
      'application/vnd.openxmlformats-officedocument.*',
      'text/plain'
    ]
  },
  
  // 视频文件
  video: {
    allowedExtensions: ['mp4', 'avi', 'mov', 'wmv', 'flv', 'webm'],
    allowedMimeTypes: ['video/*']
  },
  
  // 音频文件
  audio: {
    allowedExtensions: ['mp3', 'wav', 'flac', 'aac', 'ogg'],
    allowedMimeTypes: ['audio/*']
  },
  
  // 压缩文件
  archive: {
    allowedExtensions: ['zip', 'rar', '7z', 'tar', 'gz'],
    allowedMimeTypes: [
      'application/zip',
      'application/x-rar-compressed',
      'application/x-7z-compressed',
      'application/x-tar',
      'application/gzip'
    ]
  }
}

/**
 * 预设的图片尺寸配置
 */
export const IMAGE_DIMENSION_PRESETS = {
  // 头像
  avatar: {
    minWidth: 100,
    minHeight: 100,
    maxWidth: 500,
    maxHeight: 500,
    aspectRatio: 1, // 正方形
    aspectRatioTolerance: 0.05
  },
  
  // 横幅
  banner: {
    minWidth: 800,
    minHeight: 200,
    aspectRatio: 4, // 4:1
    aspectRatioTolerance: 0.2
  },
  
  // 缩略图
  thumbnail: {
    minWidth: 150,
    minHeight: 150,
    maxWidth: 400,
    maxHeight: 400
  },
  
  // 产品图
  product: {
    minWidth: 400,
    minHeight: 400,
    maxWidth: 2000,
    maxHeight: 2000
  }
}
